import datetime
from collections import OrderedDict
from django.db.models import Sum, Avg
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import status, mixins, viewsets
from rest_framework.pagination import PageNumberPagination
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.filters import OrderingFilter
from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet
from operator_orders.serializers import OrderInfoSerializer, DiscountCouponSerializer, Courier_CompanySerializer, \
    DiscountCouponPostSerializer, DiscountCouponPutSerializer, OrderInfoPutSerializer, ReasonSerializer, \
    ReasonUpdateSerializer, Courier_CompanyPutSerializer, Business_AddressUpdateSerializer, Business_AddressSerializer, \
    OrderSendOutSerializer, OrderSendOut_PutSerializer, Order_GoodsSerializer, OrderInfoListSerializer, \
    OrderGoodsIsReturnSerializer, FeedbackSerializer, GoodsAttribute_ChangeSerializer, Get_Business_AddressSerializer
from orders.models import OrderInfo, DiscountCoupon, Courier_Company, GoodsList, OrderGoods, Reason, Business_Address, \
    OrderInfoUpdate, ReturnDetail
from goods.models import Goods, GoodsAttribute, DiscountPackage
from django.db import transaction
from users.models import User, Feedback
from electricity_supplier_project.settings import BASE_DIR
from rest_framework import filters
import os
import time
import xlwt
from django.http import FileResponse
from utils.expressage import execute_data_query

SUCCESS_DAYS = 10  # 订单发货后10天默认收货，订单完成


class LargeResultsSetPagination(PageNumberPagination):
    page_size = 10  # 设置每页默认返回信息数量（10条信息）
    page_size_query_param = 'page_size'
    page_query_param = 'page'
    max_page_size = 150  # 前端可选的最大信息查询数量

    def get_paginated_response(self, data):
        return Response(OrderedDict([
            ('count', self.page.paginator.count),
            ('next', self.get_next_link()),
            ('previous', self.get_previous_link()),
            ('current_page', self.page.number),
            ('ResultCode', 1),
            ('results', data),
        ]))


class OrderInfoOperateViewset(ModelViewSet):
    """订单的增删查改"""
    """
    查询订单时 /operator/orderinfo/?page=2&page_size=15&ordering=create_time
    表示：查询所有订单，每页展示15条订单，展示第二页，列表排序按照订单生成时间排列
    """
    permission_classes = (IsAuthenticated,)  # 登录用户才能进行订单
    serializer_class = OrderInfoSerializer
    pagination_class = LargeResultsSetPagination  # 设置分页处理


    lookup_field = "order_id"

    def get_queryset(self):
        """获取路由上的order_id值"""
        order_id = self.kwargs.get("order_id")
        if order_id:
            queryset = OrderInfo.objects.filter(order_id=order_id)
        else:
            queryset = OrderInfo.objects.all()
        return queryset

    def update(self, request, *args, **kwargs):
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)

        order_id = self.kwargs.get("order_id")
        orderinfo = OrderInfo.objects.get(order_id=order_id)
        update_receiver = self.request.data.get('update_receiver')
        update_address = self.request.data.get('update_address')
        update_mobile = self.request.data.get('update_mobile')
        update_freight = self.request.data.get('update_freight')
        update_total_amount = self.request.data.get('update_total_amount')
        business_address = self.request.data.get('business_address')
        check_script = self.request.data.get('check_script')
        status = self.request.data.get('status')

        with transaction.atomic():  # 开启事务
            # 创建保存点，记录当前数据状态
            update_orderinfo = transaction.savepoint()
            try:
                if status == 6:
                    if instance.status == 1:
                        """ 取消订单，需要更改商品库存，如果被取消的订单存在优惠，需要改变优惠数量"""
                        goods_list = OrderGoods.objects.filter(order=orderinfo)
                        for order_goods in goods_list:
                        #     # 更改商品属性对象的库存
                            storage_amout = GoodsAttribute.objects.get(id=order_goods.goods.id).storage_amout
                            new_storage_amout = storage_amout + order_goods.count
                            ret_2 = GoodsAttribute.objects.filter(id=order_goods.goods.id).update(
                                storage_amout=new_storage_amout)  # 更新商品属性的库存
                            # 更改商品对象的销量
                            sold_num = Goods.objects.get(id=order_goods.goods.goods.id).sold_num
                            new_sold_num = sold_num - order_goods.count
                            ret_3 = Goods.objects.filter(id=order_goods.goods.goods.id).update(sold_num=new_sold_num)  # 更新商品销量
                        # 如果该订单使用了优惠券，将优惠券数量变更回去，用户绑定的优惠券对象状态变更
                        if orderinfo.discountcoupon:
                            ret_4 = DiscountCoupon.objects.filter(id=orderinfo.discountcoupon.id).update(status=False,
                                                                                                     is_show=True)  # 更新客户绑定的优惠券
                            used_counts = DiscountCoupon.objects.get(name=orderinfo.discountcoupon.name, user=None).used_counts
                            new_used_counts = used_counts - 1
                            ret_5 = DiscountCoupon.objects.filter(name=orderinfo.discountcoupon.name, user=None,
                                                                  used_counts=used_counts).update(
                                used_counts=new_used_counts)  # 更新该类型优惠券使用量
                        if orderinfo.discountpackage:
                            new_number = orderinfo.discountpackage.number - 1
                            ret_6 = DiscountPackage.objects.filter(id=orderinfo.discountpackage.id).update(number=new_number)
                        orderinfo.status = 6
                    else:
                        return Response({'message': '订单只有在未支付情况下才能取消'})
                if check_script:
                    orderinfo.check_script = check_script
                if business_address:
                    orderinfo.business_address = Business_Address.objects.get(id=business_address)

                orderinfo.save()
                if any([update_receiver, update_address, update_mobile, update_total_amount]):
                    if orderinfo.status not in [1, 2]:
                        return Response({'message': '该订单已发货，状态不可修改'})
                    if any([update_total_amount, update_freight]) and orderinfo.status == 2:
                        return Response({'message': '该订单已付款，不可更改订单金额'})
                    try:
                        old_update = OrderInfoUpdate.objects.filter(orderinfo=orderinfo).latest("create_time")
                        old_update.new = False
                        old_update.save()
                    except:
                        old_update = None
                    orderinfoupdate = OrderInfoUpdate.objects.create(
                        orderinfo=orderinfo,
                        check_user=request.user,
                        old_receiver=old_update.update_receiver if old_update else orderinfo.address.receiver,
                        update_receiver=update_receiver if update_receiver else old_update.update_receiver if old_update else orderinfo.address.receiver,
                        old_address=old_update.update_address if old_update else orderinfo.address.place,
                        update_address=update_address if update_address else old_update.update_address if old_update else orderinfo.address.place,
                        old_mobile=old_update.update_mobile if old_update else orderinfo.address.mobile,
                        update_mobile=update_mobile if update_mobile else old_update.update_mobile if old_update else orderinfo.address.mobile,
                        old_total_amount=old_update.update_total_amount if old_update else orderinfo.total_amount,
                        update_total_amount=update_total_amount if update_total_amount else old_update.update_total_amount if old_update else orderinfo.total_amount,
                        old_freight=old_update.update_freight if old_update else orderinfo.freight,
                        update_freight=update_freight if update_freight else old_update.update_freight if old_update else orderinfo.freight
                    )
                    orderinfoupdate.save()
                    if update_total_amount:
                        orderinfo.total_amount = update_total_amount
                        orderinfo.save()
                transaction.savepoint_commit(update_orderinfo)
            except:
                transaction.savepoint_rollback(update_orderinfo)
                return Response({'message': '修改失败'})
        return Response({'message': '修改完成'})

    def list(self, request, *args, **kwargs):

        search_dict = {}
        goods_name = request.query_params.get("goods_name")
        if goods_name:
            goods_id = Goods.objects.filter(name=goods_name).first().id
            search_dict["goods__goods__goods"] = goods_id

        nick_name = request.query_params.get("nick_name")
        if nick_name:
            user = User.objects.filter(nickname=nick_name).first()
            search_dict["user"] = user

        order_id = request.query_params.get("order_id")
        if order_id:
            search_dict["order_id"] = order_id

        status = request.query_params.get("status")
        if status:
            search_dict["status"] = status

        success_time_start = request.query_params.get("success_time_start")
        if success_time_start:
            search_dict["success_time__gte"] = success_time_start

        success_time_end = request.query_params.get("success_time_end")
        if success_time_end:
            search_dict["success_time__lte"] = success_time_end

        is_return = request.query_params.get("is_return")
        if is_return:
            search_dict["goods__is_return__in"] = [1, 2, 3, 4, 5, 6, 7, 8]

        queryset = OrderInfo.objects.filter(**search_dict).order_by('-update_time').distinct()
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

    def get_serializer_class(self):
        """
        提供序列化器
        """
        if self.action == 'update':
            return OrderInfoPutSerializer
        elif self.action == 'list':
            return OrderInfoListSerializer
        else:
            return OrderInfoSerializer


class OrderGoodsOperateViewset(mixins.ListModelMixin, mixins.UpdateModelMixin, viewsets.GenericViewSet):
    """
    前端传过来参数包含："order_goods_id","check"
    """
    queryset = OrderGoods.objects.exclude(is_return=0)
    serializer_class = Order_GoodsSerializer
    # permission_classes = [IsAuthenticated]

    def update(self, request, *args, **kwargs):
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        check = request.data.get('check')

        return_detail = ReturnDetail.objects.get(order_goods_id=instance)
        return_detail.check_reason = request.data.get('check_reason')
        return_detail.check_time = datetime.datetime.now()
        user = request.user
        # user = self.request.user
        if user and user.is_authenticated:
            return_detail.check_user = request.user
        else:
            return Response({'message': '用户对象不存在'})
        if check:
            if instance.is_return == 1:
                return_detail.check_results = 2
            if instance.is_return == 3:
                return_detail.check_results = 4
            if instance.is_return == 5:
                return_detail.check_results = 8
            if instance.is_return == 7:
                return_detail.check_results = 6
        else:
            if instance.is_return == 1:
                return_detail.check_results = 1
            if instance.is_return == 3:
                return_detail.check_results = 3
            if instance.is_return == 5:
                return_detail.check_results = 7
            if instance.is_return == 7:
                return_detail.check_results = 5
        return_detail.save()
        return Response(serializer.data)


class OrderGoodsIsReturnViewset(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
    queryset = OrderGoods.objects.all()
    serializer_class = OrderGoodsIsReturnSerializer


# 订单导出
class write_data_to_excel(APIView):
    def post(self, request):
        order_list = request.data.get("order_list")
        if order_list == "all":
            result = OrderInfo.objects.all().values('order_id', 'total_count', 'total_amount', 'freight', "numbers",
                                                    "discountcoupon__name", "user__nickname")
        elif order_list:
            result = OrderInfo.objects.filter(order_id__in=order_list).values('order_id', 'total_count', 'total_amount',
                                                                              'freight', "numbers",
                                                                              "discountcoupon__name", "user__nickname")
        else:
            return Response({'message': '请先选择要导出的订单'})
        headers = ['order_id', 'total_count', 'total_amount', 'freight', "numbers", "DiscountcouponName", "user"]
        # 实例化一个Workbook()对象(即excel文件)
        wbk = xlwt.Workbook()
        # 新建一个名为Sheet1的excel sheet。此处的cell_overwrite_ok =True是为了能对同一个单元格重复操作。
        sheet = wbk.add_sheet('Sheet1', cell_overwrite_ok=True)
        # 获取当前日期，得到一个datetime对象如：(2016, 8, 9, 23, 12, 23, 424000)
        today = datetime.today()
        # 将获取到的datetime对象仅取日期如：2016-8-9
        today_date = datetime.date(today)
        # 写入表头
        m = 0
        for each_header in headers:
            sheet.write(0, m, each_header)
            m += 1
        # 遍历result中的没个元素。
        var1 = 1
        var2 = 1
        var3 = 1
        var4 = 1
        var5 = 1
        var6 = 1
        var7 = 1
        for content in result:
            for key, value in content.items():
                if key == 'order_id':
                    sheet.write(var1, 0, value)
                    var1 += 1
                elif key == 'total_count':
                    sheet.write(var2, 1, value)
                    var2 += 1
                elif key == 'total_amount':
                    sheet.write(var3, 2, value)
                    var3 += 1
                elif key == 'freight':
                    sheet.write(var4, 3, value)
                    var4 += 1
                elif key == 'numbers':
                    sheet.write(var5, 4, value)
                    var5 += 1
                elif key == 'discountcoupon__name':
                    sheet.write(var6, 5, value)
                    var6 += 1
                elif key == 'user__nickname':
                    sheet.write(var7, 6, value)
                    var7 += 1
        # 以传递的name+当前日期作为excel名称保存。
        filename = 'user_' + str(today_date) + '_' + str(time.time()) + '.xls'
        file_path = os.path.join(BASE_DIR, 'download_excel', filename)
        wbk.save(file_path)
        download_file = open(file_path, 'rb')
        response = FileResponse(download_file)
        response['Content-Type'] = 'application/octet-stream'
        response['Content-Disposition'] = 'attachment;filename="%s"' % filename
        return response
        # return response({'message': '正在导出'})


class DiscountCouponOperateViewset(ModelViewSet):
    """用户优惠券的增删查改"""
    queryset = DiscountCoupon.objects.all()
    serializer_class = DiscountCouponSerializer
    pagination_class = LargeResultsSetPagination  # 设置分页处理
    lookup_field = "id"

    def get_queryset(self):
        id = self.kwargs.get("id")
        if id:
            queryset = DiscountCoupon.objects.filter(id=id)
        else:
            queryset = DiscountCoupon.objects.all().order_by('-update_time')
        return queryset

    def update(self, request, *args, **kwargs):
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        name = request.data.get('name')
        if name != instance.name:
            coupon_name = DiscountCoupon.objects.filter(name=name, user=None).first()
            if coupon_name:
                return Response({'message': '优惠券名称已存在，不得重复'})
        category = request.data.get('category')
        if category:
            if (instance.category == 3 and category != 3) or (instance.category != 3 and category == 3):
                return Response({'message': '个人专享优惠券类型不得被修改'})
        goodslist = request.data.get('goodslist')
        GoodsList.objects.filter(discountcoupon_id=instance).delete()  # 清空原有的适用商品
        if goodslist:  # 更改后类型为 部分商品适用 和 个人专享
            # 增加新添加的商品
            for i in goodslist:
                GoodsList.objects.create(discountcoupon_id=instance, cate_goods=Goods.objects.get(id=i))
        self.perform_update(serializer)
        if getattr(instance, '_prefetched_objects_cache', None):
            instance._prefetched_objects_cache = {}
        return Response(serializer.data)

    def list(self, request, *args, **kwargs):
        name = request.query_params.get("name")
        category = request.query_params.get("category")
        detail_name = request.query_params.get("detail_name")
        status = request.query_params.get("status")
        detail = {}
        search_dict = {}
        if name:
            search_dict["name"] = name
        if category:
            search_dict["category"] = category
        queryset = DiscountCoupon.objects.filter(**search_dict, is_delete=False).exclude(category__in=[1, 2],
                                                                                         user__isnull=False).order_by(
            '-update_time')
        if status:
            detail["status"] = status
        if detail_name:
            detail["name"] = detail_name
            queryset = DiscountCoupon.objects.filter(**detail, user__isnull=False, is_delete=False).order_by(
                '-update_time')
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True, context={'request': self.request})
            return self.get_paginated_response(serializer.data)
        serializer = self.get_serializer(queryset, many=True, context={'request': self.request})
        return Response(serializer.data)

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data, context={'request': self.request})
        serializer.is_valid(raise_exception=True)
        coupon_name = DiscountCoupon.objects.filter(user=None, name=request.data['name']).first()
        if coupon_name:
            return Response({'message': '优惠券名称已存在，不得重复'})
        goods_list = request.data.get('goods_list')
        user_id = request.data.get('user')
        is_show = request.data.get('is_show')
        with transaction.atomic():  # 开启事务
            save_coupon_create = transaction.savepoint()  # 创建保存点，记录当前数据状态
            try:
                discoupon = DiscountCoupon.objects.create(
                    name=request.data['name'],
                    start_time=request.data['start_time'],
                    end_time=request.data['end_time'],
                    category=request.data['category'],
                    value=request.data['value'],
                    launch_counts=request.data['launch_counts'],
                    full=request.data['full'],
                    is_show=is_show
                )
                if discoupon.category == 3:
                    try:
                        user = User.objects.get(id=user_id)
                        discoupon.user = user
                        discoupon.save()
                    except:
                        transaction.savepoint_rollback(save_coupon_create)
                        return Response({'message': '生成个人专享优惠券必须传入用户对象'})

                if goods_list and discoupon.category in [2, 3]:
                    for i in goods_list:
                        GoodsList.objects.create(discountcoupon_id=discoupon, cate_goods=Goods.objects.get(id=i))
                transaction.savepoint_commit(save_coupon_create)
            except:
                transaction.savepoint_rollback(save_coupon_create)
                return Response({'message': '优惠券生成失败'})
            baseurl = '/orders/get_coupon/2/'
            discoupon.get_url = baseurl
            discoupon.save()
        return Response(serializer.data)

    def perform_destroy(self, instance):  # 改写删除操作，软删除
        instance.is_delete = True
        instance.save()

    def get_serializer_class(self):
        """
        提供序列化器
        """
        if self.action == 'update':
            return DiscountCouponPutSerializer
        elif self.action == 'list' or 'retrieve':
            return DiscountCouponSerializer
        elif self.action == 'create':
            return DiscountCouponPostSerializer


class Company_List(APIView):
    def get(self, request):
        company_list = ['汇通快递', '百世快递',"申通", '韵达', 'EMS', '中通快运', '百世快运', '德邦', '跨越速运', '城市100', '邮政包裹', '邮政国际包裹',]
        data = company_list
        return Response(data = data)


class Courier_CompanyOperateViewset(ModelViewSet):
    """快递公司的增删查改"""
    queryset = Courier_Company.objects.all()
    serializer_class = Courier_CompanySerializer
    pagination_class = LargeResultsSetPagination
    lookup_field = "id"

    filter_backends = (DjangoFilterBackend, OrderingFilter)

    def update(self, request, *args, **kwargs):
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        name = request.data.get('name')
        q = Courier_Company.objects.filter(name=name)
        if q:
            return Response({'message': '该快递公司已经存在'})
        self.perform_update(serializer)
        if getattr(instance, '_prefetched_objects_cache', None):
            instance._prefetched_objects_cache = {}
        return Response(serializer.data)

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        name = request.data.get('name')
        q = Courier_Company.objects.filter(name=name, )
        if q:
            return Response({'message': '该快递公司已经存在'})
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def perform_destroy(self, instance):  # 改写删除操作，软删除
        instance.is_delete = True
        instance.save()

    def list(self, request, *args, **kwargs):
        queryset = Courier_Company.objects.filter(is_delete=False)
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

    def get_serializer_class(self):
        """
        提供序列化器
        """
        if self.action in 'update':
            return Courier_CompanyPutSerializer
        else:
            return Courier_CompanySerializer


class Sales_statisticsView(APIView):
    """销量统计页面查询接口"""

    def post(self, request):
        day = request.data.get('day')  # 传入数据表示请求几天的
        if day in [0, 1, 7, 30]:
            delta = datetime.timedelta(days=day)
            if day == 1:
                end_time = datetime.date.today()
            else:
                end_time = datetime.datetime.now()
            orderpay_count = OrderInfo.objects.filter(pay_time__gte=(datetime.date.today() - delta),
                                                      pay_time__lte=end_time).count()  # 付款订单数量
            moneypay_count = OrderInfo.objects.filter(pay_time__gte=(datetime.date.today() - delta),
                                                      pay_time__lte=end_time).aggregate(
                total=Sum("total_amount"))  # 当天付款金额

            orderwait_pay_count = OrderInfo.objects.filter(create_time__gte=(datetime.date.today() - delta),
                                                           create_time__lte=end_time, status=1).count()
            moneywait_pay_count = OrderInfo.objects.filter(create_time__gte=(datetime.date.today() - delta),
                                                           create_time__lte=end_time, status=1).aggregate(
                total=Sum("total_amount"))

            ordersales_count = OrderInfo.objects.filter(create_time__gte=(datetime.date.today() - delta),
                                                        create_time__lte=end_time).count()
            moneysales_count = OrderInfo.objects.filter(create_time__gte=(datetime.date.today() - delta),
                                                        create_time__lte=end_time).aggregate(total=Sum("total_amount"))
            # 查询指定的时间商品销量排行榜
            q = OrderGoods.objects.filter(create_time__gte=(datetime.date.today() - delta),
                                          create_time__lte=end_time).values_list('goods__goods__name', 'count', 'price')
            dict = {}
            for i in q:  # 遍历出每一条订单商品记录
                if i[0] not in dict:
                    dict[i[0]] = {}  # 以商品名称为键，构建一个空键值对
                    dict[i[0]]['count'] = i[1]
                    dict[i[0]]['money'] = i[1] * i[2]
                else:
                    dict[i[0]]['count'] += i[1]
                    dict[i[0]]['money'] += i[1] * i[2]
            dict_order = sorted(dict.items(), key=lambda x: x[1]['count'], reverse=True)[0:9]
            data = {
                "sale_order": dict_order,
                "orderpay_count": orderpay_count,  # 付款订单数量
                "moneypay_count": moneypay_count['total'],  # 付款金额

                "orderwait_pay_count": orderwait_pay_count,  # 待付款订单数量
                "moneywait_pay_count": moneywait_pay_count['total'],  # 待付款金额

                "ordersales_count": ordersales_count,  # 成交订单数量
                "moneysales_count": moneysales_count['total']  # 成交总金额
            }

            return Response(data=data)
        else:
            return Response({"message": "请求参数有误"})

    def get(self, request):
        year = datetime.date.today().year
        month = datetime.date.today().month
        """当天销量数据统计"""
        day_sales_money = OrderInfo.objects.filter(create_time__gte=datetime.date.today()).exclude(status=6).aggregate(
            total=Sum("total_amount"))
        day_pay_money = OrderInfo.objects.filter(pay_time__gte=datetime.date.today()).aggregate(
            total=Sum("total_amount"))
        day_wait_pay_money = OrderInfo.objects.filter(create_time__gte=datetime.date.today(), status=1).aggregate(
            total=Sum("total_amount"))
        day_order_counts = OrderInfo.objects.filter(create_time__gte=datetime.date.today()).count()
        day_pay_money_avg = OrderInfo.objects.filter(create_time__gte=datetime.date.today()).exclude(
            status=6).aggregate(Avg('total_amount'))

        """昨天销量数据统计"""
        ysday_sales_money = OrderInfo.objects.filter(
            create_time__gte=(datetime.date.today() - datetime.timedelta(1)),
            create_time__lte=datetime.date.today()).exclude(
            status=6).aggregate(total=Sum("total_amount"))
        ysday_pay_money = OrderInfo.objects.filter(
            pay_time__gte=(datetime.date.today() - datetime.timedelta(1)),
            pay_time__lte=datetime.date.today()).aggregate(
            total=Sum("total_amount"))
        ysday_wait_pay_money = OrderInfo.objects.filter(
            create_time__gte=(datetime.date.today() - datetime.timedelta(1)),
            create_time__lte=datetime.date.today(), status=1).aggregate(
            total=Sum("total_amount"))
        ysday_order_counts = OrderInfo.objects.filter(
            create_time__gte=(datetime.date.today() - datetime.timedelta(1)),
            create_time__lte=datetime.date.today(), ).count()
        ysday_pay_money_avg = OrderInfo.objects.filter(
            create_time__gte=(datetime.date.today() - datetime.timedelta(1)),
            create_time__lte=datetime.date.today(), ).exclude(
            status=6).aggregate(Avg('total_amount'))

        """本月销量数据统计"""
        month_sales_money = OrderInfo.objects.filter(
            create_time__year=year, create_time__month=month).exclude(status=6).aggregate(
            total=Sum("total_amount"))
        month_pay_money = OrderInfo.objects.filter(
            create_time__year=year, pay_time__month=month).aggregate(total=Sum("total_amount"))
        month_wait_pay_money = OrderInfo.objects.filter(
            create_time__year=year, create_time__month=month, status=1).aggregate(
            total=Sum("total_amount"))
        month_order_counts = OrderInfo.objects.filter(
            create_time__year=year, create_time__month=month).count()
        month_pay_money_avg = OrderInfo.objects.filter(
            create_time__year=year, create_time__month=month).exclude(status=6).aggregate(
            Avg('total_amount'))

        """今年的销量统计"""
        year_sales_money = OrderInfo.objects.filter(create_time__year=year).exclude(status=6).aggregate(
            total=Sum("total_amount"))
        year_pay_money = OrderInfo.objects.filter(pay_time__year=year).aggregate(total=Sum("total_amount"))
        year_wait_pay_money = OrderInfo.objects.filter(create_time__year=year, status=1).aggregate(
            total=Sum("total_amount"))
        year_order_counts = OrderInfo.objects.filter(create_time__year=year).count()
        year_pay_money_avg = OrderInfo.objects.filter(create_time__year=year).exclude(status=6).aggregate(
            Avg('total_amount'))

        count_today = {
            "day_sales_money": day_sales_money['total'],  # 当天成交订单总金额
            "day_pay_money": day_pay_money['total'],  # 当天支付总金额
            "day_wait_pay_money": day_wait_pay_money['total'],  # 当天待支付总金额
            "day_order_counts": day_order_counts,  # 当天订单数量
            "day_pay_money_avg": day_pay_money_avg['total_amount__avg'],  # 当天交易价格平均金额（客单价）
        }

        count_ysday = {
            "ysday_sales_money": ysday_sales_money['total'],
            "ysday_pay_money": ysday_pay_money['total'],
            "ysday_wait_pay_money": ysday_wait_pay_money['total'],
            "ysday_order_counts": ysday_order_counts,
            "ysday_pay_money_avg": ysday_pay_money_avg['total_amount__avg'],
        }

        count_month = {
            "month_sales_money": month_sales_money['total'],
            "month_pay_money": month_pay_money['total'],
            "month_wait_pay_money": month_wait_pay_money['total'],
            "month_order_counts": month_order_counts,
            "month_pay_money_avg": month_pay_money_avg['total_amount__avg'],
        }

        count_year = {
            "year_sales_money": year_sales_money['total'],
            "year_pay_money": year_pay_money['total'],
            "year_wait_pay_money": year_wait_pay_money['total'],
            "year_order_counts": year_order_counts,
            "year_pay_money_avg": year_pay_money_avg['total_amount__avg']
        }
        data = [count_today, count_ysday, count_month, count_year]
        return Response(data=data)


class ReasonOperateViewset(ModelViewSet):
    """退换货原因的增删查改"""
    queryset = Reason.objects.all()
    serializer_class = ReasonSerializer
    pagination_class = LargeResultsSetPagination
    filter_backends = (DjangoFilterBackend, OrderingFilter)
    lookup_field = "id"

    def update(self, request, *args, **kwargs):
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        id = self.kwargs.get("id")
        explain = self.request.data.get('explain')
        obj = Reason.objects.get(id=id)
        q = Reason.objects.filter(explain=explain, return_type=obj.return_type)
        if q:
            return Response({'message': '该原因已经存在'})
        self.perform_update(serializer)
        if getattr(instance, '_prefetched_objects_cache', None):
            instance._prefetched_objects_cache = {}

        return Response(serializer.data)

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        explain = request.data.get('explain')
        return_type = request.data.get('return_type')
        q = Reason.objects.filter(explain=explain, return_type=return_type)
        if q:
            return Response({'message': '该原因已经存在'})
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def perform_destroy(self, instance):  # 改写删除操作，软删除
        instance.is_delete = True
        instance.is_enabled = False
        instance.save()

    def list(self, request, *args, **kwargs):  # 改写查询操作，软删除后查询不可见
        search_dict = {}
        return_type = request.query_params.get("return_type")
        if return_type:
            search_dict["return_type"] = return_type
        is_enabled = request.query_params.get("is_enabled")
        if is_enabled:
            search_dict["is_enabled"] = is_enabled
        queryset = Reason.objects.filter(**search_dict, is_delete=False)
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

    def get_serializer_class(self):
        """
        提供序列化器
        """
        if self.action in 'update':
            return ReasonUpdateSerializer
        else:
            return ReasonSerializer


class Business_AddressOperateViewset(ModelViewSet):
    """退换货地址的增删查改"""
    queryset = Business_Address.objects.all()
    serializer_class = Business_AddressSerializer
    pagination_class = LargeResultsSetPagination
    lookup_field = "id"

    def update(self, request, *args, **kwargs):
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        name = self.request.data.get('name')
        q = Business_Address.objects.filter(name=name)
        if q:
            return Response({'message': '该名称已经存在'})
        self.perform_update(serializer)
        if getattr(instance, '_prefetched_objects_cache', None):
            instance._prefetched_objects_cache = {}
        return Response(serializer.data)

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        name = request.data.get('name')
        q = Business_Address.objects.filter(name=name, )
        if q:
            return Response({'message': '该名称已经存在'})

        self.perform_create(serializer)
        return Response({"message": "OK"})

    def perform_destroy(self, instance):  # 改写删除操作，软删除
        instance.is_delete = True
        instance.save()

    def list(self, request, *args, **kwargs):  # 改写查询操作，软删除后查询不可见
        queryset = Business_Address.objects.filter(is_delete=False)
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)

    def get_serializer_class(self):
        """
        提供序列化器
        """
        if self.action in 'update':
            return Business_AddressUpdateSerializer
        else:
            return Business_AddressSerializer


class Send_Out_Viewset(mixins.ListModelMixin, mixins.UpdateModelMixin, viewsets.GenericViewSet):
    """发货接口"""
    queryset = OrderInfo.objects.filter(status=2)
    serializer_class = OrderSendOutSerializer
    pagination_class = LargeResultsSetPagination  # 设置分页处理
    lookup_field = "order_id"

    def update(self, request, *args, **kwargs):
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        if instance.status != 2:
            return Response({"message": "只有待发货订单才能发货"})
        instance.status = 3  # 订单更改为待收货
        instance.send_time = datetime.datetime.now()  # 记录发货时间
        instance.success_time = datetime.datetime.now() + datetime.timedelta(days=SUCCESS_DAYS)  # 生成默认收货时间
        instance.save()
        self.perform_update(serializer)
        if getattr(instance, '_prefetched_objects_cache', None):
            instance._prefetched_objects_cache = {}
        return Response({"message": "发货成功"})

    def get_serializer_class(self):
        """
        提供序列化器
        """
        if self.action in 'update':
            return OrderSendOut_PutSerializer
        else:
            return OrderSendOutSerializer


class Feedback_Viewset(mixins.ListModelMixin, viewsets.GenericViewSet):
    pagination_class = LargeResultsSetPagination  # 设置分页处理
    queryset = Feedback.objects.all()
    serializer_class = FeedbackSerializer
    filter_backends = (DjangoFilterBackend, filters.SearchFilter,)
    filter_fields = ('suggestion_id',)


class Change_Goods_Viewset(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
    queryset = GoodsAttribute.objects.all()
    serializer_class = GoodsAttribute_ChangeSerializer


class Get_Business_AddressViewset(mixins.ListModelMixin,viewsets.GenericViewSet):
    queryset = Business_Address.objects.filter(is_delete=False)
    serializer_class = Get_Business_AddressSerializer

# 后台订单定时任务处理
from apscheduler.schedulers.background import BackgroundScheduler
from django_apscheduler.jobstores import DjangoJobStore, register_events, register_job

try:
    scheduler = BackgroundScheduler()
    scheduler.add_jobstore(DjangoJobStore(), "default")
    """ 每天扫描订单，待收货状态订单查询订单收货时间 """
    @register_job(scheduler, 'cron',day_of_week='mon-sun',hour='0', minute='30', second='00',id='0')
    def my_job():
        time_now = datetime.datetime.now()
        queryset =OrderInfo.objects.filter(status=3)
        print(queryset)
        for order in queryset:
            if order.obtain_time is None:
                try:
                    content = execute_data_query(order.numbers,order.courier_company)
                    time = content.get("result").get("list")[0].get("time")
                    order.obtain_time = time
                    order.save()
                except:
                    pass
            if time_now > order.success_time:
                order.status = 5
                order.save()
    register_events(scheduler)
    scheduler.start()
except Exception as e:
    scheduler = BackgroundScheduler()
    print(e)
    # 有错误就再次启动定时器
    scheduler.start()


